using System;
using System.Web.Mvc;
using DNT.RavenQA.Core.Models;
using DNT.RavenQA.Web.Infrastructure.Commands;
using DNT.RavenQA.Web.Infrastructure.Filters;
using log4net;
using Raven.Abstractions.Exceptions;
using Raven.Client;

namespace DNT.RavenQA.Web.Controllers
{
    public abstract class ContributeController : ControllerBase
    {
        protected ContributeController(IDocumentSession session, ILog log)
            : base(session, log) { }

        [UnitOfWork]
        [Authorize]
        public JsonResult VoteUp(Int32 id)
        {
            return Vote(VoteCommandFactory.BuildUp(RouteData.Values["controller"] as String, id, CurrentUser));
        }

        [UnitOfWork]
        [Authorize]
        public JsonResult VoteDown(Int32 id)
        {
            return Vote(VoteCommandFactory.BuildDown(RouteData.Values["controller"] as String, id, CurrentUser));
        }

        protected JsonResult Vote(VoteCommand command)
        {
            Object result;
            DocumentSession.Advanced.UseOptimisticConcurrency = true;

            try
            {
                var count = command.Execute(DocumentSession);
                result = new
                             {
                                 Error = String.Empty,
                                 Value = count.Result.TotalAmount,
                                 Id = command.InputParameter.ContributeId,
                                 ContributeType = count.Result.ContributeType == typeof(Question) ? "question" : "answer"
                             };
            }
            catch (NonExistingContributeException)
            {
                result = new { Error = "Contribute doesn't exist.", Value = 0 };
            }
            catch (AlreadyVotedQuestionException)
            {
                result = new { Error = "Cannot vote same contribute twice.", Value = 0 };
            }
            catch (ConcurrencyException)
            {
                result = new { Error = "Server error.", Value = 0 };
            }

            return Json(result);
        }
    }
}